
import java.util.Date;
import java.text.SimpleDateFormat;

class VagaController {

    int totalCurso = 0;
    int totalBeneficio = 0;
    ConvenioService convenioService;
    VagaService     vagaService;
    SolicitacaoService solicitacaoService;

    Date hoje = new Date();
    SimpleDateFormat formatador  = new SimpleDateFormat('dd/MM/yyyy hh:MM:ss');

    /*
     * Se a url vier sem action redireciona para a create
     */
    def index  = {
        redirect(action: "create");
    };

    /*
     * Closure que lista as vagas que estão inativas.
     * Utilizada pelo atendente para ativar as vagas.
    */
    def listaVagasInativas   = {
        if (!verificaLogon()) {
            return;
        }
        params.max = Math.min(params.max ? params.int('max') : 10, 100);
        //busca as vagas Inativas
        def vagaInstance = Vaga.findAllByStatus(0);
        if(vagaInstance){
            render(view:"list", model:[vagaInstanceList:vagaInstance, vagaInstanceTotal:vagaInstance.count(), vagaInstance:vagaInstance]);
        }else{
            flash.message = "Não existem vagas para moderar!";
            render(view:"list", model: [vagaInstanceList:new Vaga(), vagaInstanceTotal:0, vagaInstance:vagaInstance]);
        }
    }
   

    /*
     * Closure que lista as vagas cadastradas para a Unidade Concedente que esta logada.
     * Só lista as vagas da Unidade Concedente que está logada.
    */
    def list   = {
        if (!verificaLogon()) {
            return;
        };
        if (!verificaConvenio()) {
            return;
        };
        params.max = Math.min(params.max ? params.int('max') : 10, 100);
        // Busca as vagas da Unidade Concedente.
        def uc = UnidadeConcedente.findById(session.pessoa.id)
        def vagaInstance = Vaga.findAllByUnidadeConcedente(uc);
        if(vagaInstance){
            [vagaInstanceList: vagaInstance, vagaInstanceTotal: vagaInstance.count(), vagaInstance: vagaInstance];
        }else{
            flash.message = "Não existem vagas cadastradas!";
            [vagaInstanceList: new Vaga(), vagaInstanceTotal: 0, vagaInstance: vagaInstance];
        }
    }

    /*
     * Closure que carrega a tela de cadastro
     */
    def create = {
        if (!verificaLogon()) {
            return;
        }
        if (!verificaConvenio()) {
            return;
        }
        def vagaInstance = new Vaga();
        return [vagaInstance: vagaInstance];
    }

    
    /*
     * Closure que recebe os dados do formulário e grava.
     */
    def save   = {
        if (!verificaLogon()) {
            return;
        }
        if (!verificaConvenio()) {
            return;
        }
        def vagaInstance = new Vaga(params);
        vagaInstance.dtCadastro = Date.parse('dd/MM/yyyy hh:MM:ss',formatador.format(hoje));
        if (vagaInstance.save(flush: true)) {
            flash.message = "Dados cadastrados com sucesso!";
            redirect(action: "edit", id: vagaInstance.id);
        }else {
            render(view:"create",model: [vagaInstance: vagaInstance]);
        }
    };

    /*
     * Closure que grava os cursos.
     * CursoVagaInstance rece os atributos e os parametros.
     * findByVagaANDCurso verifica se já existe o curso cadastrado para esta vaga.
     */
    def saveCurso   = {
        if (!verificaLogon()) {
            return;
        }
        if (!verificaConvenio()) {
            return;
        }
        def cursoVagaInstance = new CursoVaga(params);
        if(CursoVaga.findByVagaAndCurso(cursoVagaInstance.vaga, cursoVagaInstance.curso)){
            flash.message = "Este curso ja está cadastrado para esta vaga.";
            redirect(action: "edit", id: cursoVagaInstance.vaga.id);
        }else{
            if (cursoVagaInstance.save(flush: true)) {
                flash.message = "Curso cadastrado com sucesso!";
                redirect(action: "edit", id: cursoVagaInstance.vaga.id);
            }else {
                flash.message = "Não foi possível cadastrar o Curso!";
                redirect(action: "edit", id: cursoVagaInstance.vaga.id);
            }
            
        }
    };

    /*
     * Closure que grava os beneficios.
     * CursoVagaInstance rece os atributos e os parametros.
     * findByVagaANDBeneficio verifica se já existe o beneficio cadastrado para esta vaga.
     */
    def saveBeneficio   = {
        if (!verificaLogon()) {
            return;
        }
        if (!verificaConvenio()) {
            return;
        }
        def beneficioVagaInstance = new BeneficioVaga(params);
        if(BeneficioVaga.findByVagaAndBeneficio(beneficioVagaInstance.vaga, beneficioVagaInstance.beneficio)){
            flash.message = "Este Beneficio ja está cadastrado para esta vaga.";
            redirect(action: "edit", id: beneficioVagaInstance.vaga.id);
        }else{
            if (beneficioVagaInstance.save(flush: true)) {
                flash.message = "Beneficio cadastrado com sucesso!";
                redirect(action: "edit", id: beneficioVagaInstance.vaga.id);
            }else {
                flash.message = "Não foi possível cadastrar o Beneficio!";
                redirect(action: "edit", id: beneficioVagaInstance.vaga.id);
            }

        }
    };

    /*
     * Closure que carrega os dados para tela de edição.
     * Verifica se a vaga que está sendo editada é da Unidade Concedente que está logada.
     * Busca os Cursos e os Beneficios da Vaga.
     * Recebe o id da Unidade Concedente da session.
     */
    def edit   = {
        if (!verificaLogon()) {
            return;
        }
        def vagaInstance = Vaga.findById(params.id);
        def unidadeConcedenteInstance = UnidadeConcedente.findById(session.pessoa.id);
        //verifica se a vaga é da Unidade Concedente
        if(Vaga.findByIdAndUnidadeConcedente(vagaInstance.id, unidadeConcedenteInstance) || session.pessoa.authorities.contains(Role.findByAuthority('ROLE_ADMIN')) || session.pessoa.authorities.contains(Role.findByAuthority('ROLE_ATENDENTE'))){
            def cursoInstance = new Curso().findAll();
            //busca os cursos
            def cursoInstanceList = Curso.executeQuery("SELECT c FROM Curso c, CursoVaga cv, Vaga v WHERE v.id = cv.vaga.id AND cv.curso.id = c.id AND v.id =? ORDER BY c.descricao",[vagaInstance.id]);
            if(cursoInstanceList){
                totalCurso = cursoInstanceList.count();
            }
            def beneficioInstance = new Beneficio().findAll();
            //busca os beneficios
            def beneficioInstanceList = Beneficio.executeQuery("SELECT b FROM Beneficio b, BeneficioVaga bv, Vaga v WHERE v.id = bv.vaga.id AND bv.beneficio.id = b.id AND v.id =? ORDER BY b.descricao",[vagaInstance.id])
            if(beneficioInstanceList){
                totalBeneficio = beneficioInstanceList.count();
            }

            // Busca curriculos enviados para a vaga.
            def envioVagaInstance = EnvioVaga.findAllByVaga(vagaInstance);
            if(envioVagaInstance == null){
                envioVagaInstance = new EnvioVaga();
            }

            //envia os dados para tela.
            if (vagaInstance){
                return [vagaInstance           : vagaInstance,
                        cursoInstance          : cursoInstance,
                        cursoInstanceList      : cursoInstanceList,
                        cursoInstanceTotal     : totalCurso,
                        beneficioInstance      : beneficioInstance,
                        beneficioInstanceList  : beneficioInstanceList,
                        beneficioInstanceTotal : totalBeneficio,
                        envioVagaInstanceList  : envioVagaInstance];
            }else {
                flash.message="Vaga não encontrada!";
                redirect(action: "create");
            }
        }else{
            flash.message="Sem permissão para acessar esta vaga.";
            redirect(action: "create");
        }
    };

    /*
     * Closure que grava as alterações
     * Verifica se a vaga que está sendo atualizada é da Unidade Concedente logada.
     */
    def update   = {
        if (!verificaLogon()) {
            return;
        }
        // carrega os dados
        def vagaInstance = Vaga.get(params.id);
        if(!vagaInstance.dtFechamento){
            if(!vagaService.vagaPossuiTce(vagaInstance)){
                vagaInstance.properties = params;
                if(vagaInstance.save(flush: true)){
                    flash.message = "Vaga atualizada com sucesso.";
                    redirect(action: "edit", id: vagaInstance.id);
                }else {
                    flash.message = "Não foi possível atualizar a vaga.";
                    render(view:"edit",model: [vagaInstance : vagaInstance]);
                }
            }else{
                flash.message = "Não é possível alterar a vaga, já possui TCE vinculado.";
                redirect(action:'edit', id:vagaInstance.id);
            }
        }else{
            flash.message = "Vagas fechadas não podem ser alteradas.";
            redirect(action:'edit', id:vagaInstance.id);
        }
    };

    /*
     * Closure que exclui os Cursos relacionados a vaga.
     * Recebe o id da vaga e o id do curso por get.
     */
    def deleteCurso = {
        if (!verificaLogon()) {
            return;
        }
        def cursoInstance     = Curso.findById(params.idc);
        def vagaInstance      = Vaga.findById(params.idv);
        def cursoVagaInstance = CursoVaga.findByVagaAndCurso(vagaInstance, cursoInstance);
        cursoVagaInstance.delete();
        flash.message = "Curso excluído com sucesso.";
        redirect(action: "edit", id: vagaInstance.id);
    };

    /*
     * Closure que exclui os Beneficios relacionados a vaga.
     * Recebe o id da vaga e o id do beneficio por get.
     **/
    def deleteBeneficio = {
        if (!verificaLogon()) {
            return;
        }
        def beneficioInstance     = Beneficio.findById(params.idb);
        def vagaInstance          = Vaga.findById(params.idv);
        def beneficioVagaInstance = BeneficioVaga.findByVagaAndBeneficio(vagaInstance, beneficioInstance);
        beneficioVagaInstance.delete();
        flash.message = "Beneficio excluído com sucesso.";
        redirect(action: "edit", id: vagaInstance.id);
    };

    /*
     * Closure responsável pela exibição dos dados.
     * Verifica se a vaga que está sendo exibida é da Unidade Concedente logada.
     * Recebe o id da vaga da lista de vagas e o id da Unidade Concedente da sessão.
     */
    def enviaVaga   = {
        if (!verificaLogon()) {
            return;
        }
        def vagaInstance = Vaga.get(params.id);
        //busca os cursos da vaga
        def cursoInstanceList = Curso.executeQuery("SELECT c FROM Curso c, CursoVaga cv, Vaga v WHERE v.id = cv.vaga.id AND cv.curso.id = c.id AND v.id =? ORDER BY c.descricao",[vagaInstance.id]);
        //busca os beneficios
        def beneficioInstanceList = Beneficio.executeQuery("SELECT b FROM Beneficio b, BeneficioVaga bv, Vaga v WHERE v.id = bv.vaga.id AND bv.beneficio.id = b.id AND v.id =? ORDER BY b.descricao",[vagaInstance.id])
        if (vagaInstance) {
            [vagaInstance          : vagaInstance,
             cursoInstanceList     : cursoInstanceList,
             beneficioInstanceList : beneficioInstanceList];
        }else {
            flash.message="Vaga não encontrado!";
            redirect(action: "list");
        }
    };


    /*
     * Closure responsável pela exibição dos dados.
     * Verifica se a vaga que está sendo exibida é da Unidade Concedente logada.
     * Recebe o id da vaga da lista de vagas e o id da Unidade Concedente da sessão.
     */
    def show   = {
        if (!verificaLogon()) {
            return;
        }
        def vagaInstance              = Vaga.findById(params.id);
        def unidadeConcedenteInstance = UnidadeConcedente.findById(session.pessoa.id);
        //busca os cursos
        def cursoInstanceList         = Curso.executeQuery("SELECT c FROM Curso c, CursoVaga cv, Vaga v WHERE v.id = cv.vaga.id AND cv.curso.id = c.id AND v.id =? ORDER BY c.descricao",[vagaInstance.id]);
        //busca os beneficios
        def beneficioInstanceList     = Beneficio.executeQuery("SELECT b FROM Beneficio b, BeneficioVaga bv, Vaga v WHERE v.id = bv.vaga.id AND bv.beneficio.id = b.id AND v.id =? ORDER BY b.descricao",[vagaInstance.id])
        // Busca curriculos enviados para a vaga.
        def envioVagaInstanceList     = EnvioVaga.findAllByVaga(vagaInstance);
        // verifica se a vaga é da Unidade Concedente
        if(Vaga.findByIdAndUnidadeConcedente(vagaInstance.id, unidadeConcedenteInstance) || session.pessoa.authorities.contains(Role.findByAuthority('ROLE_ADMIN')) || session.pessoa.authorities.contains(Role.findByAuthority('ROLE_ATENDENTE'))){
            if (vagaInstance) {
                [vagaInstance          : vagaInstance,
                 cursoInstanceList     : cursoInstanceList,
                 beneficioInstanceList : beneficioInstanceList,
                 envioVagaInstanceList : envioVagaInstanceList];
            }else {
                flash.message="Vaga não encontrado!";
                redirect(action: "list");
            }
        }else{
            flash.message="Sem permissão para acessar esta vaga.";
            redirect(action: "create");
        }
    };


    /*
     * Closure utilizada para pesquisa de vagas pelos estgiários.
     * A vaga só é exibida depois de ativada e não finalizada.
     *
     */
    def pesquisar = {
        if (!verificaLogon()) {
            return;
        }

        String filtros   = "";
        String tables    = "";
        String group     = "";
        def vagaInstance = "";

        if(params.palavra){
            filtros += " AND (v.cargo like '%"+ params.palavra +"%'";
            filtros += " OR v.atribuicoes like '%"+ params.palavra +"%'";
            filtros += " OR v.observacoes like '%"+ params.palavra +"%'";
            filtros += " OR v.perfil like '%"+ params.palavra +"%')";
        }

        if(params.atividade){
            filtros += " AND v.atividade = "+ params.atividade;
        }

        if(params.cidade){
            tables  += ", UnidadeConcedente uc, Endereco e ";
            filtros += " AND v.unidadeConcedente.id = uc.id"
            filtros += " AND uc.id = e.pessoa.id AND e.cidade.id="+params.cidade;
        }

        if(params.curso){
            tables  += ", CursoVaga cv ";
            filtros += " AND (cv.vaga.id = v.id AND cv.curso.id="+params.curso+")";
            group   += " GROUP BY cv.curso";

        }

        def buscaInstance = params;
        // verifica se algum parametro foi preenchido.
        if(params.palavra || params.atividade || params.cidade || params.curso){
            params.max = Math.min(params.max ? params.int('max') : 10, 100);
            vagaInstance = Vaga.executeQuery("SELECT v "+
                                             "FROM Vaga v "+ tables +
                                             "WHERE v.status=1 "+
                                             "  AND v.qtdeVagas > 0 "+ filtros +
                                             group+"");
            if(vagaInstance){
                render(view:"pesquisar",model: [vagaInstanceList: vagaInstance,
                                                vagaInstanceTotal: vagaInstance.count(),
                                                vagaInstance: vagaInstance,
                                                buscaInstance: buscaInstance]);
            }else{
                flash.message = "Não foram encontradas vagas!";
                [vagaInstanceList: new Vaga(), vagaInstanceTotal: 0, vagaInstance: vagaInstance];
            }
        }else{

            vagaInstance = Vaga.executeQuery("SELECT v FROM Vaga v WHERE v.status=1 AND v.qtdeVagas > 0 ");
            if(vagaInstance){
                render(view:"pesquisar",model: [vagaInstanceList: vagaInstance,
                                                vagaInstanceTotal: vagaInstance.count(),
                                                vagaInstance: vagaInstance,
                                                buscaInstance: buscaInstance]);
            }else{
                flash.message = "Não foram encontradas vagas!";
                [vagaInstanceList: new Vaga(), vagaInstanceTotal: 0];
            }
        }
    }

    /*
     * Closure ativa a vaga.
     */
    def ativarVaga = {
        if (!verificaLogon()) {
            return;
        }
        def vagaInstance = Vaga.get(params.id);
        if(vagaInstance){
            if(CursoVaga.findByVaga(vagaInstance)){
                //grava a ativação.
                vagaInstance.properties = params;
                if (vagaInstance.save(flush: true)) {

                    flash.message = "Vaga ativada com sucesso!";
                    redirect(action:"edit", id:vagaInstance.id);
                }else {
                    flash.message = "Não foi possível ativar a vaga!";
                    redirect(action:"edit", id:vagaInstance.id);
                }
            }else{
                flash.message = "Não é possivel ativar uma vaga que não possui curso.";
                redirect(action:"edit", id:vagaInstance.id);
            }
        }else{
            flash.message = "Vaga não encontrada.";
            redirect(action:"edit", id:vagaInstance.id);
        }

    }

    /*
     * Closure desativa os cadastro.
     */
    def desativarVaga   = {
        if (!verificaLogon()) {
            return;
        }
        def vagaInstance = Vaga.get(params.id);
        vagaInstance.properties = params;
        //grava a desativação.
        if (vagaInstance.save(flush: true)) {
            flash.message = "Vaga desativada com sucesso!";
            redirect(action:"edit", id:vagaInstance.id);
        }else {
            flash.message = "Não foi possível desativar a vaga!";
            redirect(action:"edit", id:vagaInstance.id);
        }
    }

    /*
     * Método que verifica se o usuário está logado.
     * Se não estiver logado é redirecionado para home
     */
    private boolean verificaLogon() {
        if(!session["pessoa"]){
            flash.message = "Você precisa estar logado para acessar esta página.";
            redirect(controller:'login', action:'auth');
            return false;
        }

        return true;
    }

    /*
     * Método que verifica se tem convênio ativo.
     */
    private boolean verificaConvenio() {
        Colaborador colaboradorInstance = Colaborador.findById(session.pessoa.id);
        if (!convenioService.possuiConvenioAtivo(colaboradorInstance)) {
            flash.message = "Você não possui convênio ativo. <a href='#'>Solicitar convênio</a>";
            redirect(controller:'unidadeConcedente', action:'edit');
            return false;
        }

        return true;
    }

}

